<template>
  <div class="demo-1">
    <el-row class="mb-4">
      <el-button type="primary" @click="handleClick1">直接挂载元素</el-button>
      <el-button type="primary" @click="handleClick2">优化挂载元素</el-button>
    </el-row>
    <ul class="demo-ul">
      <li v-for="item in liNodeList" :key="item">{{ item }}</li>
    </ul>
    <ul class="demo-ul demo-ul-pro"></ul>
  </div>
</template>

<script lang="ts" setup>
import { ref } from "vue";
import { ElButton } from "element-plus";

const total = 10000; //  总条数
const liNodeList = ref<any[]>([]);

function handleClick1() {
  const list: any[] = [];
  for (let index = 0; index < total; index++) {
    list.push(index);
  }
  liNodeList.value = list;
}

function handleClick2() {
  // 一次插入 20 条，如果觉得性能不好就减少
  const once = 20;
  // 渲染数据总共需要几次
  const loopCount = total / once;
  let countOfRender = 0;
  let ul = document.querySelector(".demo-ul-pro");
  /**
   * 下一次重绘之前更新动画帧所调用的函数(即上面所说的回调函数)
   * 该回调函数会被传入DOMHighResTimeStamp参数，该参数与performance.now()的返回值相同
   * timestamp 毫秒时间。表示开始去执行回调函数的时刻
   */
  function add(timestamp: number) {
    console.log("====", countOfRender, timestamp);
    // 优化性能，插入不会造成回流
    const fragment = document.createDocumentFragment();
    for (let i = 0; i < once; i++) {
      const li = document.createElement("li");
      li.innerText = Math.floor(Math.random() * total).toString();
      fragment.appendChild(li);
    }
    ul?.appendChild(fragment);
    countOfRender += 1;
    loop();
  }
  function loop() {
    if (countOfRender < loopCount) {
      window.requestAnimationFrame(add);
      // add();
    }
  }
  loop();
}
</script>

<style scoped>
.demo-ul {
  display: inline-block;
  margin-left: 10px;
  width: 200px;
  height: 500px;
  overflow: auto;
  border: 1px solid #f00;
}
</style>
